#include "../coredef.h"

#include "cppdef.h"

/******************************************************************
* 関 数 名 : CppLineMain
* 機    能 :
* 引    数 : VOID
* 戻 り 値 : S4
* 	　　　:１．　正常終了時：	COEXIT_SUCCESS
* 　　　　　 ：２．　致命エラー：	COEXIT_FATAL
*       :３． 警告終了　：　　　 COEXIT_WARNING
* 詳細内容 :
*******************************************************************/
S4 CppLineMain(VOID)
{
	BOOL bGotFileName = FALSE;
	U2 kindRet = TRUE;
	AST getMax = 0;
	S4 convertRet = 0;
	PSZ buf = NULL;
	PSZ convertStr = NULL;
	PSZ result = NULL;
	U2 ret = COEXIT_SUCCESS;
	S4 getTmpToken = 0;
	AST nNewDirInfo = 0;
	AST astStart = CUR_TOKEN_INDEX;
	AST astEnd = CppTokenGetLastOne();
	S4 RetInt;

	/* テーブルKIND_TRUEFALSESTATの最後の行の属性USHORT_TRUEFALSE　は　FALSEである場合 ,EXIT_SUCCESS　を返す*/
	getMax = stCppDirectiveIFGroupAccess.getMax();
	kindRet = stCppDirectiveIFGroupAccess.state.get( getMax );
	if (kindRet != TRUE)
	{
		FATAL_ON_FATAL(CppTokensDelAll());
		return(COEXIT_SUCCESS);
	}
	/* テーブルKIND_DIRECTIVEINFOに1行を追加する */
	FATAL_ON_FALSE(stCoreDirectiveInfoAccess.alloc(1));
	/* テーブルKIND_DIRECTIVEINFOの追加した行のULONG_DIRECTIVEKIND属性に　CPPDEF_INCを設定する  */
	nNewDirInfo = stCoreDirectiveInfoAccess.getMax();
	stCoreDirectiveInfoAccess.kind.set(nNewDirInfo, CPPDEF_LINE);
	/* 位置情報取得し、設定 */
	RetInt = CppLocSetDirectiveScope(nNewDirInfo);
	if( RetInt != COEXIT_SUCCESS )
	{
		return RetInt;
	}


	/*前処理字句があるかどうか判定*/
	if( CppTokenGetNextToken( TRUE, FALSE ) == COEXIT_FINISHED )    /* 前処理字句がなし*/
	{
		CppThrowWarning( CPP_LINE_FORMAT_ILLEGAL,
				stCoreDirectiveInfoAccess.locScope.get(nNewDirInfo),
				NULL, NULL );
		return( COEXIT_SUCCESS );
	}

	/* CppRepTmpToken　をコールする*/
	getTmpToken = CppRepTmpToken( astStart, &astEnd );


	/*戻り値はEXIT_FATALである場合のみ */
	if( getTmpToken == COEXIT_FATAL )
	{
		FATAL_ON_FATAL(CppTokensDelAll());
		return( COEXIT_FATAL );
	}

	/* 戻り値は正常終了でない場合 */
	if( getTmpToken != COEXIT_SUCCESS )
	{
		FATAL_ON_FATAL(CppTokensDelAll());
		return( COEXIT_SUCCESS );
	}
	CppTokenResetLastOne(astEnd);
	if( CppTokenIsFinished() ){
		CppThrowWarning( CPP_LINE_FORMAT_ILLEGAL,
				stCoreDirectiveInfoAccess.locScope.get(nNewDirInfo),
				NULL, NULL );
		return( COEXIT_SUCCESS );
	}
	kindRet = stCppTokenAccess.tokenKind.get(CUR_TOKEN_INDEX);
	if( kindRet == xPPTOKEN_VSPACE || kindRet == xPPTOKEN_HSPACE ){
		if( CppTokenGetNextToken( TRUE, FALSE ) == COEXIT_FINISHED )    /* 前処理字句がなし*/
		{
			CppThrowWarning( CPP_LINE_FORMAT_ILLEGAL,
					stCoreDirectiveInfoAccess.locScope.get(nNewDirInfo),
					NULL, NULL );
			return( COEXIT_SUCCESS );
		}
	}
	kindRet = stCppTokenAccess.tokenKind.get(CUR_TOKEN_INDEX);
	if( kindRet == xPPTOKEN_PPNUM )
	{
		/* 前処理数を整数に変更する( strtol ) */
		convertStr = stCppTokenAccess.name.get( CUR_TOKEN_INDEX );
		convertRet = strtol( convertStr, &result, 10 );

		/* 前処理数を全部整数に変更できない場合 */
		if( *result != '\0' )
		{
			CppThrowWarning( CPP_LINE_LINENO_ILLEGAL,
					stCoreDirectiveInfoAccess.locScope.get(nNewDirInfo),
					convertStr, NULL );
			ret = COEXIT_SUCCESS;
		}
		else if( convertRet <= 0 /*|| convertRet > 32767 */)
		{
			CppThrowWarning( CPP_LINE_LINENO_OVERFLOW,
					stCoreDirectiveInfoAccess.locScope.get(nNewDirInfo),
					convertStr, NULL );
		}
		stCoreDirectiveInfoAccess.s4_param.set( nNewDirInfo, convertRet );
		/* 変更した整数をテーブルKIND_DIRECTIVEINFOの追加した行のLONG_LINENO属性に設定する */
		getMax = stCppNestFileInfoAccess.getMax();
		stCppNestFileInfoAccess.logicLine.set( getMax, convertRet  );

	}else{
		CppThrowWarning( CPP_LINE_FORMAT_ILLEGAL,
				stCppTokenAccess.codeScp.get(CUR_TOKEN_INDEX),
				stCppTokenAccess.name.get(CUR_TOKEN_INDEX), NULL );
		FATAL_ON_FATAL(CppTokensDelAll());
		return( COEXIT_SUCCESS );
	}
	getTmpToken = CppTokenGetNextToken( TRUE, FALSE );
	while( getTmpToken == COEXIT_SUCCESS )
	{
		kindRet = stCppTokenAccess.tokenKind.get( CUR_TOKEN_INDEX );
		/* if  取得した前処理字句は　xPPTOKEN_STRである場合 */
		if( kindRet == xPPTOKEN_STR && bGotFileName == FALSE)
		{
			buf = stCppTokenAccess.name.get( CUR_TOKEN_INDEX );
			if( *buf == 'L' )
			{
				CppThrowWarning( CPP_LINE_FILEPATH_ILLEGAL,
						stCppTokenAccess.codeScp.get(CUR_TOKEN_INDEX),
						stCppTokenAccess.name.get(CUR_TOKEN_INDEX), NULL );
				ret = COEXIT_SUCCESS;
			}

			/* テーブルKIND_CURRENTINFOの最後の行のSTR_FILENAME属性に前処理字句の文字列を設定する */
			getMax = stCppNestFileInfoAccess.getMax();
			stCppNestFileInfoAccess.filePath.set( getMax, buf );
			stCoreDirectiveInfoAccess.str_param.set( nNewDirInfo, buf );
			bGotFileName = TRUE;
		}
		else if( kindRet ==  xPPTOKEN_NEXTLINE )
		{
			break;
		}
		else
		{
			CppThrowWarning( CPP_LINE_FILEPATH_ILLEGAL,
					stCppTokenAccess.codeScp.get(CUR_TOKEN_INDEX),
					stCppTokenAccess.name.get(CUR_TOKEN_INDEX), NULL );
		}
		getTmpToken = CppTokenGetNextToken( TRUE, FALSE );
	}
	FATAL_ON_FATAL(CppTokensDelAll());
	return( ret );
}




